package service

import (
	"batbat-backend/app/model"
	"batbat-backend/library/jwt"
	"batbat-backend/library/response"
	"github.com/gogf/gf/errors/gerror"
	"github.com/gogf/gf/frame/g"
	"github.com/gogf/gf/net/ghttp"
)

// Middleware 中间件服务
var Middleware = middleware{}

type middleware struct{}

// Login 登录中间件, 解析请求头中的token并将用户上下文存入Context中, 是一个全局中间件
func (m *middleware) Login(r *ghttp.Request) {
	// 获取token
	token := r.GetHeader(jwt.HeaderKey)
	if token == "" { // 请求未携带token
		r.Middleware.Next()
		return // 不再执行后续内容
	}
	// 校验token
	userContext, err := jwt.Verify(token)
	if err != nil { // 校验token失败, 直接返回错误消息
		response.ErrorS(r, 402, gerror.Newf("身份校验失败或当前登录已过期, 请尝试重新登陆: %v", err))
	}
	// 将userContext设置进入Context
	r.SetCtxVar(model.UserContextKey, userContext)
	r.Middleware.Next()
}

// NeedLogin 必须要登陆才能够通过此中间件
func (m *middleware) NeedLogin(r *ghttp.Request) {
	if !r.GetCtxVar(model.UserContextKey).IsNil() { // 用户上下文存在
		r.Middleware.Next()
		return
	}
	if r.GetHeader(jwt.HeaderKey) != "" { // 传入了jwt
		// 由于Login中间件是全局中间件, 代码执行到这里说明Login中间件暂未执行, 即中间件顺序错误
		g.Log().Warningf("Login中间件与NeedLogin中间件的执行顺序错误, url=%v", r.GetUrl())
		r.Middleware.Next()
		return
	}
	// 执行到这里说明用户并未登陆
	response.ErrorS(r, 401, gerror.Newf("暂未登陆, 无法查看该部分内容"))
}

// CORS 允许跨域请求
func (m *middleware) CORS(r *ghttp.Request) {
	r.Response.CORSDefault()
	r.Middleware.Next()
}
